home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / origami / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  15.1 KB  |  650 lines

  1. /*{{{}}}*/
  2. /*{{{  #includes*/
  3. #ifdef CONFIG_H
  4. #   include "config.h"
  5. #endif
  6.  
  7. #include <sys/types.h>
  8. #include <ctype.h>
  9. #include <string.h>
  10. #include <signal.h>
  11. #include <limits.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <unistd.h>
  15.  
  16. #define MISC_C
  17. #define I_BUFFLOOP_C
  18. #define I_DISPLAY_C
  19. #define I_GETMSG_C
  20. #define I_GETTK_C
  21. #define I_FINDS_C
  22. #define I_FOLDING_C
  23. #define I_KEYBOARD_C
  24. #define I_LOOP_C
  25. #define I_MAIN_C
  26. #define I_MESSAGES_C
  27. #define I_ORIEDT_C
  28. #define I_PROMPT_C
  29. #define I_SCREEN_C
  30. #define I_SIGNALS_C
  31. #define I_VIRTUAL_C
  32.  
  33. #include "origami.h"
  34. #include <h/envvar_str.h>
  35. #include <lib/ori_add_lib.h>
  36. /*}}}  */
  37.  
  38. /*{{{  debug stuff*/
  39. #ifdef DEBUGGING
  40.   /*{{{  l_to_a*/
  41.   private char *l_to_a(long x)
  42.   {
  43. #  define NBSIZE ((sizeof(size_t)<<2)+1)
  44.     static char number[NBSIZE];
  45.     char *s;
  46.     boolean neg;
  47.  
  48.     if ((neg=(x<0))) x= -x;
  49.     s=number+NBSIZE-1;
  50.     *s=0;
  51.     do
  52.      { *(--s)=hex_digits[x%10]; }
  53.     while ((x/=10)>0);
  54.     if (neg) *(--s)='-';
  55.     return(s);
  56.   }
  57.   /*}}}  */
  58.  
  59.   /*{{{  ocl debug*/
  60. #  ifdef OCL_DEBUG
  61.      /*{{{  variables*/
  62.      FILE *o_dumb=0;
  63.      char *o_name=0;
  64.      FILE *o_keyf=0;
  65.      char *o_key_file=0;
  66.      private boolean ocl_show_stack=False;
  67.      private int cur_stack=0;
  68.      private boolean ocl_show_max_s=False;
  69.      private int max_stack=0;
  70.      private long ocl_slowdown=0;
  71.      private boolean ocl_debug_scr=False;
  72.      private int ocl_scr_active=0;
  73.      private
  74. #     include "viewrc/name.h"
  75.      /*}}}  */
  76.  
  77.      /*{{{  ocl_key*/
  78.      public void ocl_key(int x)
  79.       { if (o_keyf)
  80.          { fputc(x,o_keyf);
  81.            fflush(o_keyf);
  82.          }
  83.       }
  84.      /*}}}  */
  85.      /*{{{  ocl_msg*/
  86.      public void ocl_msg(char*s,int i)
  87.      {
  88.        if (o_dumb)
  89.         { fprintf(o_dumb,"\t\t\t");
  90.           fprintf(o_dumb,s,i);
  91.           fprintf(o_dumb,"\n");
  92.           fflush(o_dumb);
  93.         }
  94.      }
  95.      /*}}}  */
  96.      /*{{{  ocl_get_arg_dbg*/
  97.      public void ocl_get_arg_dbg(TOKEN a,char *s)
  98.      {
  99.        if (o_dumb)
  100.         { fprintf(o_dumb,"\t\t\targ %d %s\n",a,s);
  101.           fflush(o_dumb);
  102.         }
  103.      }
  104.      /*}}}  */
  105.      /*{{{  ocl_debug*/
  106.      public void ocl_debug(int stack,TOKEN tok)
  107.      { if (stack!=cur_stack)
  108.         /*{{{  store stack data, handle status line*/
  109.         { if (ocl_show_stack || ocl_show_max_s) title_op(CHGTITLE);
  110.           cur_stack=stack;
  111.           if (max_stack<cur_stack) max_stack=cur_stack;
  112.         }
  113.         /*}}}  */
  114.        if (o_dumb)
  115.         /*{{{  dumb to file*/
  116.         { static long count=0;
  117.           extern TOKEN *macro_pos;
  118.  
  119.           fprintf(o_dumb,"%7ld%c%015ld=",count++,bd.m.file_changed_status?'*':' ',(long)macro_pos);
  120.           while (stack>16) { fputc('>',o_dumb);stack-=16; }
  121.           while (stack--) fputc('*',o_dumb);
  122.           if (tok>=O_NOP && tok<=O_EXE_MACRO)
  123.              fputs(dec[tok-O_NOP],o_dumb);
  124.           else if (tok>O_EXE_MACRO)
  125.              fprintf(o_dumb,"O_CALL_FIX %d",tok-O_EXE_MACRO);
  126.           else if (tok<O_NOP && tok>=' ')
  127.              fputc(tok,o_dumb);
  128.           else
  129.              fprintf(o_dumb,"%d",tok);
  130.           fputc('\n',o_dumb);
  131.           fflush(o_dumb);
  132.         }
  133.         /*}}}  */
  134.        oflush;
  135.        usleep(ocl_slowdown*1000);
  136.      }
  137.      /*}}}  */
  138.      /*{{{  o_arg_handle*/
  139.      private void o_arg_handle(char *a)
  140.      {
  141.        switch (*a++)
  142.         { case 'f':
  143.              o_name=a;
  144.              break;
  145.           case 's':
  146.              ocl_show_stack=True;
  147.              break;
  148.           case 'S':
  149.              ocl_show_max_s=True;
  150.              break;
  151.           case 't':
  152.              ocl_slowdown=atoi(a);
  153.              break;
  154.           case 'd':
  155.              ocl_debug_scr=True;
  156.              break;
  157.           case 'k':
  158.              o_key_file=a;
  159.              break;
  160.           default:
  161.              break;
  162.         }
  163.      }
  164.      /*}}}  */
  165.      /*{{{  o_info*/
  166.      private boolean o_info(unsigned char* t)
  167.      { if (ocl_debug_scr || ocl_show_stack || ocl_show_max_s)
  168.         { ustrcat(t,(unsigned char*)"(");
  169.           /*{{{  screen on/off*/
  170.           if (ocl_debug_scr)
  171.            { ustrcat(t,ocl_scr_active?(unsigned char*)"OFF":(unsigned char*)"ON");
  172.              if (ocl_show_stack || ocl_show_max_s)
  173.                 ustrcat(t,one_space);
  174.            }
  175.           /*}}}  */
  176.           /*{{{  stack*/
  177.           if (ocl_show_stack)
  178.            { ustrcat(t,(unsigned char*)"s");
  179.              ustrcat(t,i_to_ua(cur_stack));
  180.              if (ocl_show_stack || ocl_show_max_s)
  181.                 ustrcat(t,one_space);
  182.            }
  183.           if (ocl_show_max_s)
  184.            { ustrcat(t,(unsigned char*)"S");
  185.              ustrcat(t,i_to_ua(max_stack));
  186.            }
  187.           /*}}}  */
  188.           ustrcat(t,(unsigned char*)")");
  189.           return(True);
  190.         }
  191.        return(False);
  192.      }
  193.      /*}}}  */
  194. #  else
  195. #      define o_info(x) 0
  196. #  endif
  197.   /*}}}  */
  198.   /*{{{  malloc debug*/
  199. #  ifdef MALLOC_DEBUG
  200.     /*{{{  variables*/
  201.     private FILE *mf_dumb=0;
  202.     private char *mf_name;
  203.  
  204. #    ifndef MALLOC_PAKET
  205. #      define MALLOC_PAKET 0
  206. #    endif
  207.     private int m_paket=MALLOC_PAKET;
  208.     private int m_lost_rate=0;
  209.     private size_t m_limit=0;
  210.  
  211.     private size_t m_used=0;
  212.     private size_t m_frag_lost=0;
  213.  
  214.     private boolean m_show=False;
  215.     /*}}}  */
  216.  
  217.     /*{{{  mf_print*/
  218.     private void mf_print(char*s)
  219.     {
  220.       if (mf_dumb) { fputs(s,mf_dumb);fflush(mf_dumb); }
  221.     }
  222.     /*}}}  */
  223.     /*{{{  paket_malloc*/
  224.     public void *paket_malloc(size_t n)
  225.     { void *x;
  226.       char report[256];
  227.       static int no=0;
  228.  
  229.       mf_print("malloc-");
  230.       mf_print((char*)i_to_ua(++no));
  231.       mf_print(": ");
  232.       /*{{{  maybe let paket grow*/
  233.       if (m_paket) { n |= m_paket;n++; }
  234.       /*}}}  */
  235.       if (m_limit && m_used+n>m_limit)
  236.        /*{{{  limit reached*/
  237.        { strcpy(report,"limit reached, ");
  238.          strcat(report,l_to_a((long)n));
  239.          strcat(report," wanted\n");
  240.          x=0;
  241.        }
  242.        /*}}}  */
  243.       else if ((x=ORImalloc(n+sizeof(size_t))))
  244.        /*{{{  malloc ok*/
  245.        { m_used+=n;
  246.          *((int*)x)=n;
  247.          x=(void*)((char*)x+sizeof(size_t));
  248.          strcpy(report,"got ");
  249.          strcat(report,l_to_a((long)n));
  250.          strcat(report," bytes ok (");
  251.          strcat(report,l_to_a((long)m_used));
  252.          strcat(report,")\n");
  253.          title_op(CHGTITLE);
  254.          *((char*)x)='\0';
  255.        }
  256.        /*}}}  */
  257.       else
  258.        /*{{{  no more memory*/
  259.        { strcpy(report,"malloc ");
  260.          strcat(report,l_to_a((long)n));
  261.          strcat(report," wanted\n");
  262.        }
  263.        /*}}}  */
  264.  
  265.       mf_print(report);
  266.  
  267.       return(x);
  268.     }
  269.     /*}}}  */
  270.     /*{{{  paket_free*/
  271.     public void paket_free(void *p)
  272.     { char report[256];
  273.       static int no=0;
  274.  
  275.       mf_print("free---");
  276.       mf_print((char*)i_to_ua(++no));
  277.       mf_print(": ");
  278.       if (!p)
  279.        /*{{{  only report error*/
  280.          strcpy(report,"free null!\n");
  281.        /*}}}  */
  282.       else
  283.        /*{{{  free and report diff*/
  284.        { size_t n;
  285.  
  286.          p=(void*)((char*)p-sizeof(size_t));
  287.          n=*((int*)p);
  288.          ORIfree(p);
  289.          m_used-=n;
  290.          m_frag_lost+=(n*m_lost_rate)/100;
  291.          strcpy(report,"freed ");
  292.          strcat(report,l_to_a((long)n));
  293.          strcat(report," bytes (");
  294.          strcat(report,l_to_a((long)m_used));
  295.          strcat(report,")\n");
  296.          title_op(CHGTITLE);
  297.        }
  298.        /*}}}  */
  299.  
  300.       mf_print(report);
  301.     }
  302.     /*}}}  */
  303.     /*{{{  paket_realloc*/
  304.     public void *paket_realloc(void *p,size_t n)
  305.     { void *x;
  306.       size_t cp_length;
  307.  
  308.       cp_length= *(((size_t*)p)-1);
  309.       if (cp_length>n) cp_length=n;
  310.       mf_print("realloc:\n");
  311.       if ((x=paket_malloc(n)))
  312.        { memcpy(x,p,cp_length);
  313.          paket_free(p);
  314.        }
  315.       return(x);
  316.     }
  317.     /*}}}  */
  318.     /*{{{  mf_arg_handle*/
  319.     private void mf_arg_handle(char *a)
  320.     {
  321.       switch (*a++)
  322.        { case 's':
  323.             m_limit=atoi(a);
  324.             break;
  325.          case 'p':
  326.           { int i;
  327.  
  328.             m_paket=atoi(a);
  329.             for (i=0;i<m_paket;i=(i<<1)+1);
  330.             m_paket=i;
  331.             break;
  332.           }
  333.          case 'f':
  334.             mf_name=a;
  335.             break;
  336.          case '%':
  337.             m_lost_rate=atoi(a);
  338.             if (m_lost_rate<0 || m_lost_rate>100)
  339.                m_lost_rate=0;
  340.             break;
  341.          case '\0':
  342.             m_show=True;
  343.             break;
  344.          default:
  345.             break;
  346.        }
  347.     }
  348.     /*}}}  */
  349.     /*{{{  mf_info*/
  350.     private boolean mf_info(unsigned char *t)
  351.     {
  352.       if (m_show)
  353.        { ustrcat(t,(unsigned char*)"(m");
  354.          ustrcat(t,(unsigned char*)l_to_a((long)m_used));
  355.          if (m_limit)
  356.           { ustrcat(t,(unsigned char*)"-");
  357.             ustrcat(t,(unsigned char*)l_to_a((long)((m_limit-m_used-m_frag_lost)*100)/m_limit));
  358.             ustrcat(t,(unsigned char*)"%");
  359.           }
  360.          ustrcat(t,(unsigned char*)")");
  361.          return(True);
  362.        }
  363.       return(False);
  364.     }
  365.     /*}}}  */
  366. #  else
  367. #   define mf_info(x) 0
  368. #  endif
  369.   /*}}}  */
  370.   /*{{{  vir debug*/
  371. #  ifdef VIR_DEBUG
  372.      public FILE *v_dumb=0;
  373.      private char *v_name=0;
  374.      private boolean v_display=False;
  375.      private off_t v_off=0;
  376.  
  377.      /*{{{  vir_debug*/
  378.      public void vir_debug(off_t off)
  379.      { if (v_display)
  380.         { if (off!=v_off) title_op(CHGTITLE);
  381.           v_off=off;
  382.         }
  383.      }
  384.      /*}}}  */
  385.      /*{{{  vir_arg_handle*/
  386.      private void vir_arg_handle(char *a)
  387.      { switch (*a++)
  388.         { case 'f':
  389.              v_name=a;
  390.              break;
  391.           case '\0':
  392.              v_display=True;
  393.              break;
  394.           default:
  395.              break;
  396.         }
  397.      }
  398.      /*}}}  */
  399.      /*{{{  vir_info*/
  400.      private boolean vir_info(unsigned char *t)
  401.      { if (v_display)
  402.         { ustrcat(t,(unsigned char*)"(N=");
  403.           ustrcat(t,i_to_ua(vir_nodes));
  404.           if (vir_nodes)
  405.            { ustrcat(t,(unsigned char*)",");
  406.              ustrcat(t,(unsigned char*)l_to_a((long)v_off/1024));
  407.            }
  408.           ustrcat(t,(unsigned char*)")");
  409.           return(True);
  410.         }
  411.        return(False);
  412.      }
  413.      /*}}}  */
  414. #  else
  415. #    define vir_info(x) 0
  416. #  endif
  417.   /*}}}  */
  418.  
  419.   /*{{{  list of dumb files*/
  420.   typedef struct { FILE *f;char *n; } D_F;
  421.   private D_F d_f[]=
  422.    {
  423. #  ifdef OCL_DEBUG
  424.        { 0,0 },
  425. #  endif
  426. #  ifdef VIR_DEBUG
  427.        { 0,0 },
  428. #  endif
  429. #  ifdef MALLOC_DEBUG
  430.        { 0,0 },
  431. #  endif
  432.     { 0,0 }
  433.    };
  434.   /*}}}  */
  435.   /*{{{  open_dumb_file*/
  436.   private FILE *open_dumb_file(char *name)
  437.   { D_F *fn=d_f;
  438.  
  439.     if (!*name) name=DEBUG_FILE;
  440.     while (fn->n)
  441.        if (strcmp(fn->n,name))
  442.           fn++;
  443.        else
  444.           break;
  445.     if (!fn->n)
  446.        fn->f=fopen(fn->n=name,"w");
  447.  
  448.     return(fn->f);
  449.   }
  450.   /*}}}  */
  451.  
  452.   /*{{{  title_debug*/
  453.   public void title_debug(unsigned char *t)
  454.   {
  455.      if (mf_info(t) | o_info(t) | vir_info(t)) ustrcat(t,one_space);
  456.   }
  457.   /*}}}  */
  458.   /*{{{  start_debug*/
  459.   public void start_debug(void)
  460.   {
  461. #   ifdef MALLOC_DEBUG
  462.        if (mf_name)
  463.         /*{{{  open file and write limits*/
  464.         { mf_dumb=open_dumb_file(mf_name);
  465.           if (mf_dumb)
  466.            { mf_print("using limit ");
  467.              mf_print(l_to_a((long)m_limit));
  468.              mf_print(", paketsize ");
  469.              mf_print(l_to_a((long)(m_paket?(m_paket+1):0)));
  470.              mf_print("\n");
  471.              fflush(mf_dumb);
  472.            }
  473.         }
  474.         /*}}}  */
  475. #   endif
  476. #   ifdef VIR_DEBUG
  477.        if (v_name)
  478.           v_dumb=open_dumb_file(v_name);
  479. #   endif
  480. #   ifdef OCL_DEBUG
  481.        if (o_name)
  482.           o_dumb=open_dumb_file(o_name);
  483.        if (o_key_file)
  484.           o_keyf=open_dumb_file(o_key_file);
  485. #   endif
  486.   }
  487.   /*}}}  */
  488.   /*{{{  end_debug*/
  489.   public void end_debug(void)
  490.   { D_F *fn=d_f;
  491.  
  492.     while (fn->f) fclose(fn++->f);
  493.   }
  494.   /*}}}  */
  495.   /*{{{  arg_debug*/
  496.   public void arg_debug(char *a)
  497.   {
  498.     switch (*a++)
  499.      {
  500. #      ifdef MALLOC_DEBUG
  501.           case 'm':
  502.              mf_arg_handle(a);
  503.              break;
  504. #      endif
  505. #      ifdef OCL_DEBUG
  506.           case 'o':
  507.              o_arg_handle(a);
  508.              break;
  509. #      endif
  510. #      ifdef VIR_DEBUG
  511.           case 'v':
  512.              vir_arg_handle(a);
  513.              break;
  514. #      endif
  515.        default:
  516.           break;
  517.      }
  518.   }
  519.   /*}}}  */
  520. #endif
  521. /*}}}  */
  522.  
  523. /*{{{  ocl_screen_off*/
  524. public void ocl_screen_off(void)
  525. {
  526. #ifdef OCL_DEBUG
  527.   if (ocl_debug_scr)
  528.    { ocl_scr_active++;
  529.      ori_assert(bd.scr.cur_shift_w<=LINELEN,"shift-check");
  530.      title_op(PRTTITLE);
  531.    }
  532.   else
  533. #endif
  534.    { if (!scr_off++) screen_off(); }
  535. }
  536. /*}}}  */
  537. /*{{{  ocl_screen_on*/
  538. public boolean ocl_screen_on(void)
  539. {
  540. #ifdef OCL_DEBUG
  541.   if (ocl_debug_scr)
  542.    { if (!ocl_scr_active) return(True);
  543.      ocl_scr_active--;
  544.      ori_assert(bd.scr.cur_shift_w<=LINELEN,"shift-check");
  545.      title_op(PRTTITLE);
  546.  
  547.      return(False);
  548.    }
  549.   else
  550. #endif
  551.    { if (!scr_off) return(True);
  552.      if (!--scr_off)
  553.       { screen_on();
  554.         check_time_event();
  555.       }
  556.  
  557.      return(False);
  558.    }
  559. }
  560. /*}}}  */
  561. #ifndef OS_FILEPROMPT
  562.   /*{{{  fileprompt*/
  563.   public unsigned char *fileprompt(unsigned char * const n)
  564.   {
  565.     s_readprompt(n,get_msg(M_FILENAME),_POSIX_PATH_MAX,file_history);
  566.     home_expand((char*)n);
  567.     if (!*n && (bd.f.real_tail!=bd.f.real_head) && !aborted)
  568.      { ustrcpy(n,get_data(bd.f.real_tail));
  569.        if (*n) add_history(misc_history,n);
  570.      }
  571.     return(n);
  572.   }
  573.   /*}}}  */
  574. #endif
  575. /*{{{  environment-variables*/
  576. public void put_vars(void)
  577. {
  578. # define STRLEN(x) (sizeof(x)-1)
  579.   /*{{{  static vars, to hold the environment data*/
  580.   static char envfile[_POSIX_PATH_MAX+STRLEN(ORIFILE)+2]=ORIFILE "=";
  581.   static char envline[LINELEN+STRLEN(ORILINE)+2]=ORILINE "=";
  582.   static char envposx[STRLEN(ORIXPOS)+12]=ORIXPOS "=";
  583.   static char envword[LINELEN+STRLEN(ORIWORD)+2]=ORIWORD "=";
  584.   static char envposy[STRLEN(ORIYPOS)+12]=ORIYPOS "=";
  585.   static char envpid[STRLEN(ORIPID)+12]=ORIPID "=";
  586.   /*}}}  */
  587.  
  588.   /*{{{  filename*/
  589.   strcpy
  590.    ( envfile+STRLEN(ORIFILE)+1,
  591.      (char*)(bd.f.real_tail==bd.f.real_head
  592.               ? empty_text
  593.               : get_data(bd.f.real_tail))
  594.    );
  595.   putenv(envfile);
  596.   /*}}}  */
  597.   /*{{{  line,x,word*/
  598.   { char *s,*w;
  599.     int xoff;
  600. #   define lb (envline+STRLEN(ORILINE)+1)
  601.  
  602.     /*{{{  line*/
  603.     copyin((unsigned char*)lb,bd.f.current,True);
  604.     putenv(envline);
  605.     /*}}}  */
  606.     /*{{{  positionx*/
  607.     strcpy
  608.      ( envposx+STRLEN(ORIXPOS)+1,
  609.        (char*)i_to_ua
  610.                (xoff=1+bd.f.enter_spaces+scr2txt
  611.                                           ( bd.f.enter_spaces,
  612.                                             bd.scr.cursor.w,
  613.                                             (unsigned char*)lb
  614.                                           )
  615.                )
  616.      );
  617.     putenv(envposx);
  618.     /*}}}  */
  619.     /*{{{  word*/
  620.     /*{{{  append the word*/
  621.     /*{{{  s=&bd.f.current char in line*/
  622.     xoff-=bd.f.enter_spaces+1;
  623.     s=lb;
  624.     while (*s && xoff--) s++;
  625.     /*}}}  */
  626.     /*{{{  maybe move to start of word*/
  627.     if (isalnum(*(s))||(*(s)=='_'))
  628.        while ((s!=lb)&&(isalnum(*(s-1))||(*(s-1)=='_'))) s--;
  629.     /*}}}  */
  630.     /*{{{  append the word*/
  631.     w=envword+STRLEN(ORIWORD)+1;
  632.     while (*s && (isalnum(*s)||*s=='_')) *w++=*s++;
  633.     *w='\0';
  634.     /*}}}  */
  635.     /*}}}  */
  636.     putenv(envword);
  637.     /*}}}  */
  638.   }
  639.   /*}}}  */
  640.   /*{{{  positiony*/
  641.   strcpy(envposy+STRLEN(ORIYPOS)+1,(char*)i_to_ua(cur_line_no()));
  642.   putenv(envposy);
  643.   /*}}}  */
  644.   /*{{{  pid*/
  645.   strcpy(envpid+STRLEN(ORIPID)+1,(char*)i_to_ua(getpid()));
  646.   putenv(envpid);
  647.   /*}}}  */
  648. }
  649. /*}}}  */
  650.